// $Id: ContainerImpl.cpp 27 2011-09-16 13:28:08Z skagget77 $

#include "PreCompile.h"
#include "Detail/ContainerImpl.h"


using namespace IoCpp;


void ContainerImpl::DoAddModule( const std::wstring& file ) {
   std::wstring ws = file;
   ws = ws;
}


void ContainerImpl::DoAddProvider( const TypeInfo& type, const std::string& name, boost::any provider ) {
   types[type].insert(std::make_pair(name, provider));
}


boost::any ContainerImpl::DoInject( const TypeInfo& type ) const 
{
   // Find the type to inject.
   TypeCollection::const_iterator it1 = types.find(type);

   if(it1 != types.end())
   {
      // Find the default provider.
      ProviderCollection::const_iterator it2 = it1->second.find("");

      if(it2 != it1->second.end())
         return it2->second;

      // Find the first provider.
      ProviderCollection::const_iterator it3 = it1->second.begin();

      if(it3 != it1->second.end())
         return it3->second;

      throw ProviderNotFoundException(
         "Provider for type " + type.Name() + " not found in container"
      );
   }

   throw TypeNotFoundException(
      "Type " + type.Name() + " not found in container"
   );
}


boost::any ContainerImpl::DoInject( const TypeInfo& type, const std::string& name ) const 
{
   // Find the type to inject.
   TypeCollection::const_iterator it1 = types.find(type);

   if(it1 != types.end())
   {
      // Find the named provider.
      ProviderCollection::const_iterator it2 = it1->second.find(name);

      if(it2 != it1->second.end())
         return it2->second;
      
      throw ProviderNotFoundException(
         "Provider for type " + type.Name() + " not found in container"
      );
   }

   throw TypeNotFoundException(
      "Type " + type.Name() + " not found in container"
   );
}


ProviderNameCollection ContainerImpl::DoGetAllProviders( const TypeInfo& type ) const 
{
   // Find the type to enumerate the providers for.
   TypeCollection::const_iterator it1 = types.find(type);

   if(it1 != types.end())
   {
      ProviderNameCollection providerNames;

      // Copy provider names from the internal map.
      for(ProviderCollection::const_iterator it2 = it1->second.begin(); 
            it2 != it1->second.end(); ++it2)
         providerNames.push_back(it2->first);

      return providerNames;
   }

   throw TypeNotFoundException(
      "Type " + type.Name() + " not found in container"
   );
}


void ContainerImpl::DoScan( const FileCollection& , const FileCollection& , const PathCollection& , const PathCollection& , bool  )
{

}
